package ecom.entity;

import java.util.Date;
import java.util.Set;

import javax.ejb.Remote;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import exceptions.IdentifiantInvalide;

/**
 * eCommerce Application Sample for J2EE Training. Commande d'un client.
 */
@Entity
@Remote(CommandeRemote.class)
@Table(name = "commande")
public class Commande implements CommandeRemote {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id_commande")
    private Long id;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "date_commande")
    private Date date;

    @Column(name = "montant_commande")
    private double montant;

    @ManyToOne(fetch = FetchType.EAGER, targetEntity = Account.class)
    @JoinColumn(name = "account_commande")
    private AccountRemote account;

    @OneToMany(mappedBy = "commande", fetch = FetchType.EAGER, targetEntity = Ligne.class)
    private Set<LigneRemote> lignes;

    public Commande() {
    }

    /**
     * Constructeur.
     * 
     */
    public Commande(Long id, Date date, double montant, AccountRemote account,
	    Set<LigneRemote> lignes) {
	super();
	this.id = id;
	this.date = new Date(date.getTime());
	this.montant = montant;
	this.account = account;
	this.lignes = lignes;
    }

    public static void verifierReference(Long reference)
	    throws IdentifiantInvalide {
	if (reference == null) {
	    throw new IdentifiantInvalide(
		    "L'identifiant de la Commande est obligatoire : "
			    + reference);
	}
    }

    @Override
    public Long getId() {
	return this.id;
    }

    @Override
    public void setId(Long id) {
	this.id = id;
    }

    @Override
    public Date getDate() {
	return new Date(this.date.getTime());
    }

    @Override
    public void setDate(Date date) {
	this.date = new Date(date.getTime());
    }

    @Override
    public double getMontant() {
	return this.montant;
    }

    @Override
    public void setMontant(double montant) {
	this.montant = montant;
    }

    @Override
    public AccountRemote getCompte() {
	return this.account;
    }

    @Override
    public void setCompte(AccountRemote account) {
	this.account = account;
    }

    @Override
    public Set<LigneRemote> getLignes() {
	return this.lignes;
    }

    @Override
    public void setLignes(Set<LigneRemote> lignes) {
	for (LigneRemote ligne : lignes) {
	    ligne.setCommande(this);
	}
	this.lignes = lignes;
    }

    @Override
    public int hashCode() {
	int prime = 31;
	int result = 1;
	result = prime
		* result
		+ ((account == null || account.getIban() == null) ? 0 : account
			.getIban().hashCode());
	result = prime * result + ((date == null) ? 0 : date.hashCode());
	result = prime * result + ((id == null) ? 0 : id.hashCode());
	long temp;
	temp = Double.doubleToLongBits(montant);
	result = prime * result + (int) (temp ^ (temp >>> 32));
	return result;
    }

    @Override
    public boolean equals(Object obj) {
	if (this == obj) {
	    return true;
	}
	if (obj == null) {
	    return false;
	}
	if (!(obj instanceof Commande)) {
	    return false;
	}
	Commande other = (Commande) obj;
	if (account == null) {
	    if (other.account != null) {
		return false;
	    }
	} else if (!account.getIban().equals(other.account.getIban())) {
	    return false;
	}
	if (date == null) {
	    if (other.date != null) {
		return false;
	    }
	} else if (!date.equals(other.date)) {
	    return false;
	}
	if (id == null) {
	    if (other.id != null) {
		return false;
	    }
	} else if (!id.equals(other.id)) {
	    return false;
	}
	if (Double.doubleToLongBits(montant) != Double
		.doubleToLongBits(other.montant)) {
	    return false;
	}
	return true;
    }

    @Override
    public String toString() {
	return "Commande [id=" + id + ", date=" + date + ", montant=" + montant
		+ ", compte=" + account.getIban() + ", lignes=" + lignes + "]";
    }
}